1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package sun.util;
27
28 import java.lang.ref.SoftReference;
29 import java.util.Enumeration;
30 import java.util.LinkedList;
31 import java.util.List;
32 import java.util.Locale;
33 import java.util.Map;
34 import java.util.MissingResourceException;
35 import java.util.Set;
36 import java.util.concurrent.ConcurrentHashMap;
37 import java.util.spi.TimeZoneNameProvider;
38 import sun.util.calendar.ZoneInfo;
39 import sun.util.resources.LocaleData;
40 import sun.util.resources.OpenListResourceBundle;
41
42
43
44
45 public final class TimeZoneNameUtility {
46
47
48
49
50 private static ConcurrentHashMap<Locale, SoftReference<OpenListResourceBundle>> cachedBundles =
51 new ConcurrentHashMap<Locale, SoftReference<OpenListResourceBundle>>();
52
53
54
55
56 private static ConcurrentHashMap<Locale, SoftReference<String[][]>> cachedZoneData =
57 new ConcurrentHashMap<Locale, SoftReference<String[][]>>();
58
59
60
61
62 public static final String[][] getZoneStrings(Locale locale) {
63 String[][] zones;
64 SoftReference<String[][]> data = cachedZoneData.get(locale);
65
66 if (data == null || ((zones = data.get()) == null)) {
67 zones = loadZoneStrings(locale);
68 data = new SoftReference<String[][]>(zones);
69 cachedZoneData.put(locale, data);
70 }
71
72 return zones;
73 }
74
75 private static final String[][] loadZoneStrings(Locale locale) {
76 List<String[]> zones = new LinkedList<String[]>();
77 OpenListResourceBundle rb = getBundle(locale);
78 Enumeration<String> keys = rb.getKeys();
79 String[] names = null;
80
81 while(keys.hasMoreElements()) {
82 String key = keys.nextElement();
83
84 names = retrieveDisplayNames(rb, key, locale);
85 if (names != null) {
86 zones.add(names);
87 }
88 }
89
90 String[][] zonesArray = new String[zones.size()][];
91 return zones.toArray(zonesArray);
92 }
93
94
95
96
97 public static final String[] retrieveDisplayNames(String id, Locale locale) {
98 OpenListResourceBundle rb = getBundle(locale);
99 return retrieveDisplayNames(rb, id, locale);
100 }
101
102 private static final String[] retrieveDisplayNames(OpenListResourceBundle rb,
103 String id, Locale locale) {
104 LocaleServiceProviderPool pool =
105 LocaleServiceProviderPool.getPool(TimeZoneNameProvider.class);
106 String[] names = null;
107
108
109
110 if (pool.hasProviders()) {
111 names = pool.getLocalizedObject(
112 TimeZoneNameGetter.INSTANCE,
113 locale, rb, id);
114 }
115
116 if (names == null) {
117 try {
118 names = rb.getStringArray(id);
119 } catch (MissingResourceException mre) {
120
121 }
122 }
123
124 return names;
125 }
126
127 private static final OpenListResourceBundle getBundle(Locale locale) {
128 OpenListResourceBundle rb;
129 SoftReference<OpenListResourceBundle> data = cachedBundles.get(locale);
130
131 if (data == null || ((rb = data.get()) == null)) {
132 rb = LocaleData.getTimeZoneNames(locale);
133 data = new SoftReference<OpenListResourceBundle>(rb);
134 cachedBundles.put(locale, data);
135 }
136
137 return rb;
138 }
139
140
141
142
143
144 private static class TimeZoneNameGetter
145 implements LocaleServiceProviderPool.LocalizedObjectGetter<TimeZoneNameProvider,
146 String[]>{
147 private static final TimeZoneNameGetter INSTANCE =
148 new TimeZoneNameGetter();
149
150 public String[] getObject(TimeZoneNameProvider timeZoneNameProvider,
151 Locale locale,
152 String requestID,
153 Object... params) {
154 assert params.length == 0;
155 String[] names = null;
156 String queryID = requestID;
157
158 if (queryID.equals("GMT")) {
159 names = buildZoneStrings(timeZoneNameProvider, locale, queryID);
160 } else {
161 Map<String, String> aliases = ZoneInfo.getAliasTable();
162
163 if (aliases != null) {
164
165
166 if (aliases.containsKey(queryID)) {
167 String prevID = queryID;
168 while ((queryID = aliases.get(queryID)) != null) {
169 prevID = queryID;
170 }
171 queryID = prevID;
172 }
173
174 names = buildZoneStrings(timeZoneNameProvider, locale, queryID);
175
176 if (names == null) {
177
178
179 names = examineAliases(timeZoneNameProvider, locale,
180 queryID, aliases, aliases.entrySet());
181 }
182 }
183 }
184
185 if (names != null) {
186 names[0] = requestID;
187 }
188
189 return names;
190 }
191
192 private static String[] examineAliases(TimeZoneNameProvider tznp, Locale locale,
193 String id,
194 Map<String, String> aliases,
195 Set<Map.Entry<String, String>> aliasesSet) {
196 if (aliases.containsValue(id)) {
197 for (Map.Entry<String, String> entry : aliasesSet) {
198 if (entry.getValue().equals(id)) {
199 String alias = entry.getKey();
200 String[] names = buildZoneStrings(tznp, locale, alias);
201 if (names != null) {
202 return names;
203 } else {
204 names = examineAliases(tznp, locale, alias, aliases, aliasesSet);
205 if (names != null) {
206 return names;
207 }
208 }
209 }
210 }
211 }
212
213 return null;
214 }
215
216 private static String[] buildZoneStrings(TimeZoneNameProvider tznp,
217 Locale locale, String id) {
218 String[] names = new String[5];
219
220 for (int i = 1; i <= 4; i ++) {
221 names[i] = tznp.getDisplayName(id, i>=3, i%2, locale);
222 if (i >= 3 && names[i] == null) {
223 names[i] = names[i-2];
224 }
225 }
226
227 if (names[1] == null) {
228
229 names = null;
230 }
231
232 return names;
233 }
234 }
235 }